﻿// 麻省理工学院许可证
//
// 版权所有 (c) 2021-2023 zuohuaijun，大名科技（天津）有限公司  联系电话/微信：18020030720  QQ：515096995
//
// 特此免费授予获得本软件的任何人以处理本软件的权利，但须遵守以下条件：在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
//
// 软件按“原样”提供，不提供任何形式的明示或暗示的保证，包括但不限于对适销性、适用性和非侵权的保证。
// 在任何情况下，作者或版权持有人均不对任何索赔、损害或其他责任负责，无论是因合同、侵权或其他方式引起的，与软件或其使用或其他交易有关。

using Newtonsoft.Json.Serialization;
using Org.BouncyCastle.Utilities.Encoders;
using System.Dynamic;
using System.Security.Cryptography;
using System.Text.RegularExpressions;

namespace Jim.K3Cloud;
public static  class K3CloudExtension
{
    /// <summary>SHA1签名</summary>
    /// <param name="arr"></param>
    /// <returns></returns>
    public static string GetSignature(string[] arr)
    {
        Array.Sort<string>(arr, (IComparer<string>)StringComparer.Ordinal);
        string s = string.Join("", arr);
        byte[] hash = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(s));
        StringBuilder stringBuilder= new StringBuilder();
        foreach (byte num in hash)
            stringBuilder.AppendFormat("{0:x2}", (object)num);
        return stringBuilder.ToString();
    }

    /// <summary>SHA256 转换为 Hex字符串（UTF8）</summary>
    /// <param name="data">源字符串</param>
    /// <returns>哈希Hex字符串</returns>
    public static string Sha256Hex(this string data) => Sha256Hex(data, Encoding.UTF8);

    public static string Sha256Hex(this string data, Encoding encoding) => Sha256Hex(encoding.GetBytes(data));

    public static string Sha256Hex(this byte[] bytes)
    {
        using (SHA256 shA256 = SHA256.Create())
            return Hex.ToHexString(shA256.ComputeHash(bytes));
    }


    public static bool IsJson(this string value,ref JToken jToken)
    {
        if(string.IsNullOrEmpty(value)) return false;
        try{
            jToken = JToken.Parse(value);
            return true;
        }catch{
            Regex regex = new Regex(@"{.*?}$"); // 假设只想提取大括号之间的部分
            Match match = regex.Match(value);
            if(match.Success)
            {
                string json = match.Value;
                jToken = JToken.Parse(value);
            }
            else {
                jToken = JToken.FromObject(value);
            }
            return false;
        }
    }

    public static JToken TryGetToken(this JToken jToken, string propName, ref JToken value, bool deleteProp = false)
    {
        value= null;
        if(jToken is JObject jObject)
        {
            if(jObject.ContainsKey(propName))
            {
                value= jObject[propName].DeepClone();
                if(deleteProp)
                {
                    jObject.Remove(propName);
                    return jObject;
                }

                jObject.Remove(propName);
                return jObject;
            }
        }
        return jToken;
    }


    public static bool TryGetValue<T>(this JToken jToken, string propName, out T value, T defaultValue= default(T), bool deleteProp = false)
    {
        bool IsContain = false;
        value= defaultValue;
        if(jToken is JObject jObject && jObject.ContainsKey(propName))
        {
            IsContain = true;
            try
            {
                JToken propToken = jObject[propName];
                value= propToken.ToObject<T>();
                if(deleteProp)
                {
                    jObject.Remove(propName);
                }
            }
            catch{ }
            jObject.Remove(propName);
        }
        return IsContain;
    }


    public static bool IsJsonString(this string str,ref string json)
    {
        bool isJson = false;
        Regex regex = new Regex(@"{.*?}$"); // 假设只想提取大括号之间的部分
        Match match = regex.Match(str);
        if(match.Success)
        {
            json = match.Value;
            isJson = true;
        }
        return isJson;
    }


    public static object BuildCustomerData(this ISdkRequest request, string? formId = null, object? data = null)
    {
        dynamic obj = new ExpandoObject();
        if(!string.IsNullOrEmpty(formId))
            obj.FormId = formId;
        if(data != null)
            obj.Data = data;
        return obj;
    }

}
